﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using WebMatrix.WebData;
using System.Web.UI;
using System.Web.Script.Services;
using System.Web.Services;

using OAuthProtocol;
using Dropbox.Api;
using CloudTree.Models;
using CloudTree.Filters;

namespace CloudTree.Controllers
{
    [InitializeSimpleMembership]
    public class DropboxController : Controller
    {
        private const string ConsumerKey = "07hhp48nehsni1u";
        private const string ConsumerSecret = "fqzqelyk8f8ikd9";

        public bool AlreadyPopulated
        {
            get
            {
                return (Session["AlreadyPopulated"] == null ? false : (bool)Session["AlreadyPopulated"]);
            }
            set
            {
                Session["AlreadyPopulated"] = (bool)value;
            }
        }

        [HttpPost]
        public JsonResult GetDropboxTreeData(string path)
        {
            Uri uri = new Uri(DropboxRestApi.BaseUri);
            Files rootNode = new Files();
            if (AlreadyPopulated == false)
            {
                rootNode.attr = new FileAttribute();
                rootNode.data = "Dropbox";
                rootNode.attr.id = "dropbox";
                PopulateDropboxTree(uri, rootNode, path);
                AlreadyPopulated = true;
                return Json(rootNode);
            }
            else if (AlreadyPopulated == true)
            {
                PopulateDropboxTree(uri, rootNode, path);
                return Json(rootNode);
            }
            else 
            {
                return null;
            }
        }


        public void PopulateDropboxTree(Uri baseUri, Files node, string path)
        {
            int userID = WebSecurity.CurrentUserId;

            if (node.children == null)
            {
                node.children = new List<Files>();
            }

            using (UsersContext db = new UsersContext())
            {
                //Assign the token & secret from the database based on the userID of the currently logged in user
                string token =
                    (from t in db.UserProfiles
                     where t.UserId == userID
                     select t.DrBxToken).FirstOrDefault();
                string secret =
                    (from t in db.UserProfiles
                     where t.UserId == userID
                     select t.DrBxSecret).FirstOrDefault();

                var stack = new Stack<Files>();

               // OAuthToken accessToken = new OAuthToken(token, secret);//simple storage
                DropboxApi api = new DropboxApi(ConsumerKey, ConsumerSecret, new OAuthToken(token, secret));

                Files rootFile = api.GetFiles("dropbox", path);//Retreive each file in the root directory of the dropbox account
              //  stack.Push(rootFile);

              /*  foreach (Files f in stack)
                {
                    if (f.Icon == "folder" || f.Icon == "" || f.Icon == "")
                    {
                        stack.Push(f);
                    }
                    else 
                    {
                    }
                }
               */
                //Now I have all of the files/folders from the root directory,I will need to add these to a list, which will subsequently be called by jstree 
                foreach (var fifo in rootFile.Contents)
                {
                    // create a new node and assign the values according to each iteration of the for loop
                    Files dtmN = new Files();
                    dtmN.attr = new FileAttribute();
                    dtmN.attr.id = String.Format("{0}dropbox{1}", baseUri.ToString(), fifo.Path);
                    dtmN.data = fifo.Path;
                    dtmN.Size = fifo.Size;
                    dtmN.Icon = fifo.Icon;
                    dtmN.nodeUri = new Uri(new Uri(DropboxRestApi.BaseUri), String.Format("metadata/{0}{1}", fifo.Root, fifo.Path));

                    node.children.Add(dtmN); // add the node to the "master" node
                }
            }
        }
        //the method to populate a TreeView with drectories, subdirectories, etc.
        public void PopulateTree(string dir, JSTreeTestMod node)
        {
            if (node.children == null)
            {
                node.children = new List<JSTreeTestMod>();
            }
            // get the information of the directory
            DirectoryInfo directory = new DirectoryInfo(dir);
            // loop through each subdirectory
            foreach (DirectoryInfo d in directory.GetDirectories())
            {
                // create a new node
                JSTreeTestMod t = new JSTreeTestMod();
                t.attr = new JsTreeAttribute();
                t.attr.id = d.FullName;
                t.data = d.Name.ToString();
                // populate the new node recursively
                PopulateTree(d.FullName, t);
                node.children.Add(t); // add the node to the "master" node
            }
            //Then, loop through each file in the directory, and add these as nodes
            foreach (FileInfo f in directory.GetFiles())
            {
                // create a new node
                JSTreeTestMod t = new JSTreeTestMod();
                t.attr = new JsTreeAttribute();
                t.attr.id = f.FullName;
                t.data = f.Name.ToString();
                // add it to the "master"
                node.children.Add(t);
            }
        }

       
        [HttpPost]
        public JsonResult GetTreeData()
        {
            if (AlreadyPopulated == false)
            {
                JSTreeTestMod rootNode = new JSTreeTestMod();
                rootNode.attr = new JsTreeAttribute();
                rootNode.data = "ROOT";
                string rootPath = Request.MapPath("/Root");
                rootNode.attr.id = rootPath;
                PopulateTree(rootPath, rootNode);
                AlreadyPopulated = true;
                return Json(rootNode);
            }
            else
            {
                return null;
            }
        }


        [HttpPost]
        public ActionResult MoveData(string path, string destination)
        {
            // get the file attributes for file or directory
            FileAttributes attPath = System.IO.File.GetAttributes(path);

            FileAttributes attDestination = System.IO.File.GetAttributes(path);

            FileInfo fi = new FileInfo(path);

            //detect whether its a directory or file
            if ((attPath & FileAttributes.Directory) == FileAttributes.Directory)
            {
                if ((attDestination & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    MoveDirectory(path, destination);
                }
            }
            else
            {
                System.IO.File.Move(path, destination + "\\" + fi.Name);
            }
            AlreadyPopulated = false;
            return null;
        }

        [HttpPost]
        public ActionResult CreateFolder(string path, string newname)
        {
            Directory.CreateDirectory(path + "\\" + newname);
            AlreadyPopulated = false;
            return null;
        }

        public void MoveDirectory(string source, string target)
        {
            var stack = new Stack<Folders>();
            stack.Push(new Folders(source, target));

            while (stack.Count > 0)
            {
                var folders = stack.Pop();

                Directory.CreateDirectory(
                    Path.Combine(target, source.Split(Path.DirectorySeparatorChar).Last()));

                foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
                {
                    string targetFile = Path.Combine(folders.Target, Path.GetFileName(file));
                    if (System.IO.File.Exists(targetFile))
                    {
                        System.IO.File.Delete(targetFile);
                    }
                    System.IO.File.Move(file, targetFile);
                }

                foreach (var folder in Directory.GetDirectories(folders.Source))
                {
                    stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
                }
            }
            Directory.Delete(source, true);
        }
        public class Folders
        {
            public string Source { get; private set; }
            public string Target { get; private set; }

            public Folders(string source, string target)
            {
                Source = source;
                Target = target;
            }
        }
      
        public ActionResult DropboxDisplay()
        {
            AlreadyPopulated = false;
            int userID = WebSecurity.CurrentUserId;
            DropboxRestApi URIs = new DropboxRestApi();
            using (UsersContext db = new UsersContext())
            {
                
                //Assign the token & secret from the database based on the userID of the currently logged in user
                string token =
                    (from t in db.UserProfiles
                     where t.UserId == userID
                     select t.DrBxToken).FirstOrDefault();
                string secret =
                    (from t in db.UserProfiles
                     where t.UserId == userID
                     select t.DrBxSecret).FirstOrDefault();

                OAuthToken accessToken = new OAuthToken(token, secret);//simple storage
                DropboxApi api = new DropboxApi(ConsumerKey, ConsumerSecret, accessToken);

                Files files = api.GetFiles("dropbox","");

                return View(files);
            }
        }
        /*
        public ActionResult DropboxDisplay()
        {
            int userID = WebSecurity.CurrentUserId;

            using (UsersContext db = new UsersContext())
            {

                //Assign the token & secret from the database based on the userID of the currently logged in user
                string token =
                    (from t in db.UserProfiles
                        where t.UserId == userID
                        select t.DrBxToken).FirstOrDefault();
                string secret =
                    (from t in db.UserProfiles
                        where t.UserId == userID
                        select t.DrBxSecret).FirstOrDefault();

                OAuthToken accessToken = new OAuthToken(token, secret);//simple storage
                DropboxApi api = new DropboxApi(ConsumerKey, ConsumerSecret, accessToken);

                Dropbox.Api.File files = api.GetFiles("dropbox", "");

                return View(files);
            }
        }
         */
    }
}
